import socket
import selectors # IO多路复用选择器

server = socket.socket()
# epoll IO 多路复用 的时候不用在开非阻塞了
server.bind(('', 9000))
server.listen(1000)

# 生成一个 epoll 选择器实例
epoll_selector = selectors.EpollSelector()

# 第一个参数　服务端对象　　第二个参数　选择器　读的时候　　第三个参数　回调函数　　就是把一个函数当成参数传入另一个函数
# 这个就是reav接收
def read(connection):
    recv_data = connection.recv(1024)
    if recv_data:
        print(recv_data)
        connection.send(recv_data)
    else:
        # 断开  就取消注册
        epoll_selector.unregister(connection)
        connection.close()

# 回调函数
def accept(server):
    connection, raddr = server.accept()
    # 收数据
    epoll_selector.register(connection, selectors.EVENT_READ, read)

# 这一步其实就是  accept
epoll_selector.register(server, selectors.EVENT_READ, accept)

# 事件循环
while True:
    # 所有已经准备好的 epoll 事件 是一个列表
    events = epoll_selector.select()
    # print(events) [(xxx, 1)]
    # 第一项是我们需要的
    for key, mask in events:
        callback = key.data # 拿出 回调函数
        sock = key.fileobj  # 拿出自己注册的 socket
        callback(sock)  # 不需要关心 什么 socket和事件
